<code_style>
Весь код, который ты пишешь, должен быть максимально читаемым и понятным человеку, который будет его позже читать и править. Это правило применяется к любой задаче на программирование и к любому языку.

<principles>
- Читаемость важнее краткости. Не используй приёмы сокращения кода, если они ухудшают понимание: цепочки вложенных тернарных операторов, «умные» однострочники, избыточно плотные генераторы и comprehension, неочевидные побитовые трюки, злоупотребление лямбдами.
- Предпочитай простые, явные конструкции: промежуточные переменные с понятными именами вместо длинных выражений, ранние возвраты вместо глубокой вложенности, одно действие на строку.
- Если можно написать «короче» или «понятнее», выбирай «понятнее».
</principles>

<naming>
Каждое имя (функция, метод, класс, переменная, константа, параметр, модуль, поле) должно отражать то, что оно делает или хранит.
- Запрещены имена из одной-двух букв и безликие имена (a, b, x, tmp, data, res, f, do_it, handle), кроме общепринятых индексов в коротких циклах (i, j).
- Функции и методы называй глаголом или глагольной фразой, описывающей действие (calculate_total_price, load_player_save).
- Переменные и поля называй существительным, описывающим содержимое (remaining_health, hex_neighbor_list).
- Булевы значения называй вопросом (is_visible, has_pending_changes).
- Единицы измерения и смысл включай в имя, если это неочевидно (timeout_seconds, damage_per_tick).
- Следуй конвенции именования языка (snake_case, camelCase, PascalCase) и проекта.

Плохо:   def f(a, b): return a ** b
Хорошо:  def helper_power(base, power): return base ** power
</naming>

<documentation>
Каждая функция, метод и класс снабжается docstring или документационным комментарием на принятом в языке формате (docstring в Python, JSDoc в JS/TS, Javadoc в Java, XML-doc в C#, Doxygen в C/C++, LuaLS-аннотации в Lua и т.д.).

Документация состоит из двух частей:
1. Описание: одна-две фразы о том, что делает функция и зачем.
2. Спецификация:
   - что принимается: каждый параметр с типом и смыслом (включая допустимые диапазоны и значения по умолчанию);
   - что отдаётся: тип и смысл возвращаемого значения (и что возвращается в крайних случаях, например при пустом вводе);
   - какие исключения или ошибки возможны и когда;
   - побочные эффекты (изменение аргументов, запись в файл, сетевые вызовы, изменение глобального состояния), если они есть.

Для классов дополнительно описывай назначение класса и его публичные атрибуты.
Типы дополнительно указывай в самой сигнатуре, если язык это поддерживает (type hints, TypeScript, и т.п.).
</documentation>

<inline_comments>
Если внутри функции есть вложенные блоки (циклы, условия, try/except, with, обработчики, замыкания), перед каждым таким блоком ставь однострочный комментарий о том, что в нём происходит и зачем. Комментируй намерение («что и зачем»), а не пересказывай синтаксис («увеличиваем i на 1»).
Неочевидные места (граничные случаи, обходные решения, причины выбора алгоритма) объясняй отдельным комментарием.
</inline_comments>

<comment_language>
Комментарии и документацию пиши на языке, на котором сформулирован запрос пользователя, если в проекте не принято другое. Идентификаторы в коде пиши на английском.
</comment_language>

<formatting>
Правила пустых строк (применяются к любому языку):
- Между блоками верхнего уровня (уровни вложенности 0-1) ставь ТРИ пустые строки. К таким блокам относятся функции, классы, методы внутри класса, экраны (screen), метки (label) и аналогичные самостоятельные единицы кода.
- Когда заканчивается вложенный блок внутри такой единицы (цикл, условие, try/except, with, определение контейнера в screen Ren'Py и т.п.), после него ставь ОДНУ пустую строку, если код продолжается дальше на том же уровне или выше.
- Если по смыслу это одна инструкция, но она перенесена на несколько строк (длинный вызов функции, многострочная строка, список или словарь, выражение в скобках), после неё ставь ОДНУ пустую строку.

Правило отступов (только для Python и Ren'Py):
- Используй отступ в два пробела на уровень вложенности вместо четырёх.
</formatting>

<example language="python">
def calculate_average_score(score_list: list[float]) -> float:
  """
  Считает среднее арифметическое списка оценок.

  Args:
    score_list (list[float]): Список оценок. Не должен быть пустым.

  Returns:
    float: Среднее значение оценок.

  Raises:
    ValueError: Если список оценок пуст.
  """
  # Защита от деления на ноль: пустой список не имеет среднего
  if not score_list:
    raise ValueError("Список оценок не должен быть пустым")

  # Суммируем все оценки одним проходом
  total_score = 0.0
  for score in score_list:
    total_score += score

  return total_score / len(score_list)



def build_score_report(player_name: str, score_list: list[float]) -> str:
  """
  Формирует текстовый отчёт со средней оценкой игрока.

  Args:
    player_name (str): Имя игрока для заголовка отчёта.
    score_list (list[float]): Список оценок. Не должен быть пустым.

  Returns:
    str: Готовая строка отчёта.

  Raises:
    ValueError: Если список оценок пуст (пробрасывается из calculate_average_score).
  """
  average_score = calculate_average_score(score_list)

  # Собираем отчёт из двух частей; инструкция одна, но разнесена на строки
  report_text = (
    f"Игрок: {player_name}. "
    f"Средняя оценка: {average_score:.2f}"
  )

  return report_text
</example>

<example language="renpy">
screen inventory_screen(item_name_list):
  # Панель инвентаря: список предметов и кнопка закрытия
  vbox:
    spacing 10

    # Выводим название каждого предмета отдельной строкой
    for item_name in item_name_list:
      text item_name

    textbutton "Закрыть" action Hide("inventory_screen")



screen status_screen(player_name, remaining_health):
  # Небольшая панель со статусом игрока
  frame:
    text "[player_name]: [remaining_health] HP"
</example>

</code_style>